﻿using Learun.Application.Organization;
using Learun.Application.TwoDevelopment.ZZDT_EC;
using Learun.Util;
using Learun.Util.SqlSugar;
using Pipelines.Sockets.Unofficial.Arenas;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web.Http;
using static Learun.Application.TwoDevelopment.ZZDT_EC.IO_WorkFlowService;
using Action = Learun.Application.TwoDevelopment.ZZDT_EC.Action;

namespace Learun.Application.Web.AppApi
{

    /// <summary>
    /// 信号（By ChenGT）
    /// </summary>
    [HandlerApiLogin(FilterMode.Enforce)]
    [TokenAuthorize]
    public class WireGroupApiController : WebApiControllerBase
    {
        #region 辅助类
        /// <summary>
        /// SaveSignals 专用
        /// </summary>
        private class WireGroups
        {
            public string ID { get; set; }
            public List<ec_Wire_GroupEntity> Signals { get; set; }
        }
        #endregion
        #region 模块对象
        private ec_Wire_GroupIBLL ec_Wire_GroupIBLL = new ec_Wire_GroupBLL();
        #endregion
        #region 信号模板
        ///// <summary>
        ///// 信号列表
        ///// </summary> 
        ///// <param name="projectId">项目编号</param>
        ///// <param name="templateId">模板编号</param>
        ///// <param name="wireGroupId">信号编号</param>
        ///// <returns></returns>
        //[HttpGet]
        //public IHttpActionResult GetList(string projectId, string templateId = "", string wireGroupId = "")
        //{
        //    try
        //    {
        //        var res = ec_Wire_GroupIBLL.GetList("{\"ProjectId\":\"" + projectId + "\"}");
        //        return Success(res);
        //    }
        //    catch (Exception ex)
        //    {
        //        return Fail(ex.Message);
        //    }
        //}

        /// <summary>
        /// 所有信号(平级，不会因为<see cref="ec_Wire_GroupEntity.ParentID"/>进行排列）。
        /// 目前插件端用的是这个。
        /// </summary>
        /// <param name="projId"></param>
        /// <param name="Assigned">默认true，返回和channel关联的。false时，返回全部</param>
        /// <returns></returns>
        [HttpGet]
        public IHttpActionResult GetSignals(string projId, bool Assigned = true)
        {
            var res = new ec_Wire_GroupBLL(projId).GetList("{ProjectId:\"" + projId + "\"}", Assigned, false, true);
            return Success(res);
        }


        /// <summary>
        /// 批量保存（增、改、删）信号。
        /// </summary> 
        /// <param name="projId"></param>
        /// <param name="mode">0是默认。1表示从IO关联界面保存</param>
        /// <returns></returns>
        [HttpPost]
        public IHttpActionResult SaveSignals(string projId, string mode = "0")
        {
            //送过来的信号，也可能是完全相同的（前端1改为2，2又改回1的时候）
            try
            {
                var BLL = new ec_Wire_GroupBLL(projId);
                var asyncContent = Request.Content.ReadAsStringAsync().Result;
                var entity = asyncContent.ToObject<WireGroups>();
                var res = new List<ec_Wire_GroupEntity>();
                var messages = "";
                foreach (var item in entity.Signals)
                {
                    var id = item.Wire_Group_ID;
                    string result = BLL.SaveEntity(projId, ref id, item, mode);
                    if (!string.IsNullOrEmpty(result))
                    {
                        messages += result + "\n";
                    }
                    res.Add(item);
                }
                if (!string.IsNullOrEmpty(messages))
                {
                    return Fail(messages);
                }

                return Success(res);
            }
            catch (Exception e)
            {

                return Fail(e.Message);
            }
        }
        /// <summary>
        /// 验证信号是否可以保存，如果无法保存，返回原因
        /// </summary> 
        /// <param name="projId">项目编号</param>
        /// <param name="ActionType">0 新增，1 修改，2 准备删除，3 撤销删除， 4 彻底删除， 5 关联通道，6 审核，7 重新打开，8 关联解除, 9 回收站恢复</param>
        /// <returns></returns>
        [HttpPost]
        public IHttpActionResult CanSaveSignals(string projId, Action ActionType)
        {
            try
            {
                var BLL = new ec_Wire_GroupBLL(projId);
                var asyncContent = Request.Content.ReadAsStringAsync().Result;
                var entity = asyncContent.ToObject<WireGroups>();
                var res = new List<ec_Wire_GroupEntity>();
                var messages = "";
                foreach (var item in entity.Signals)
                {
                    string result = BLL.CanSaveEntity(projId, item, ActionType);
                    if (!string.IsNullOrEmpty(result))
                    {
                        messages += result + "\n";
                    }
                    res.Add(item);
                }
                if (!string.IsNullOrEmpty(messages))
                {
                    return Fail(messages);
                }
                return Success(res);
            }
            catch (Exception e)
            {
                return Fail(e.Message);
            }
        }

        /// <summary>
        /// 删除某个信号,同时删除虚拟点
        /// </summary> 
        /// <param name="projId"></param>
        /// <param name="WireGroupID">多个删除，按逗号隔开</param>
        /// <returns></returns>
        [HttpPost]
        public IHttpActionResult DeleteSignal(string projId, string WireGroupID)
        {

            try
            {
                var BLL = new ec_Wire_GroupBLL(projId);
                var IDs = WireGroupID.Split(',');

                foreach (var Id in IDs)
                {
                    string res = "";
                    res = BLL.DeleteEntity(projId, Id, false);
                    if (res != "")
                    {
                        return Fail(res);
                    }
                }

                return Success("OK");
            }
            catch (Exception e)
            {

                return Fail(e.Message);
            }
        }
        /// <summary>
        /// 验证信号是否可以删除，如果无法删除，返回原因
        /// </summary> 
        /// <param name="projId"></param>
        /// <param name="WireGroupID">多个删除，按逗号隔开</param>
        /// <returns></returns>
        [HttpPost]
        public IHttpActionResult CanDeleteSignals(string projId, string WireGroupID)
        {
            try
            {
                var BLL = new ec_Wire_GroupBLL(projId);
                var IDs = WireGroupID.Split(',');
                var message = "";
                foreach (var Id in IDs)
                {
                    string res = "";
                    res = BLL.DeleteEntity(projId, Id, true);
                    if (res != "")
                    {
                        message += res + "\n";
                    }
                }
                if (!string.IsNullOrEmpty(message))
                {
                    return Fail(message);
                }

                return Success("OK");
            }
            catch (Exception e)
            {

                return Fail(e.Message);
            }
        }
        #endregion
        /// <summary>
        /// 信号导入（xlsx）
        /// </summary> 
        /// <param name="projectId">项目编号</param>
        /// <param name="fileId">文件编号</param>
        /// <param name="version">版本1：1642版；2：8600版</param>
        /// <param name="update">只更新</param>
        /// <param name="templateId">模板编号(项目级时，就是空的）</param>
        /// <returns></returns>
        [HttpPost]
        public IHttpActionResult ImportSignals(string projectId, string fileId, int version, bool update = false, string templateId = "")
        {
            try
            {
                var BLL = new ec_Wire_GroupBLL();
                byte[] bytes = null;
                var res = BLL.ImportSignals(projectId, templateId, fileId, update, version);
                if (!string.IsNullOrEmpty(res))
                {
                    return Fail(res);
                }
                return Success("导入完成");
            }
            catch (Exception e)
            {
                return Fail(e.Message);
            }
        }

        /// <summary>
        /// 成品导出（xlsx）
        /// </summary>
        /// <param name="projectId">项目编号</param>
        /// <param name="version">版本1：1642版；2：8600版</param>
        /// <param name="delete">包含待删除</param>
        /// <returns></returns>
        [HttpGet]
        public void ExportSignals(string projectId, int version, bool delete = false)
        {
            if (string.IsNullOrEmpty(projectId))
            {
                return; // 空时，无意义
            }
            var reportTableName = ProjectSugar.TableName<ec_report_fileEntity>(projectId);
            ec_report_fileEntity report = null;
            byte[] bytes;
            switch (version)
            {
                case 1:
                    report = SqlSugarHelper.Db.Queryable<ec_report_fileEntity>().AS(reportTableName).First(x => x.ReportFileName == "信号清册（1642版）");
                    break;
                case 2:
                    report = SqlSugarHelper.Db.Queryable<ec_report_fileEntity>().AS(reportTableName).First(x => x.ReportFileName == "信号清册（8600版）");
                    break;
                case 3:
                    report = SqlSugarHelper.Db.Queryable<ec_report_fileEntity>().AS(reportTableName).First(x => x.ReportFileName == "信号清册（8600版单行）");
                    break;
            }
            if (report == null || string.IsNullOrEmpty(report.FolderId))
            {
                bytes = System.Text.Encoding.UTF8.GetBytes("找不到名为【信号清册（1642版）】或【信号清册（8600版）】的报表文件，或者报表文件没有上传其背后的excel模板文件。");
            }
            else
            {
                var BLL = new ec_Wire_GroupBLL();
                bytes = BLL.ExportSignals(projectId, delete, version, report.FolderId);
            }

            var stream = new MemoryStream(bytes);
            FileDownHelper.DownLoad(stream, $"报警点表{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx");
        }

        /// <summary>
        /// 查询信号历史和日志
        /// </summary>
        /// <param name="projId">项目ID</param>
        /// <param name="wireGroupIds">信号ID，多个用都逗号隔开</param>
        /// <returns></returns>
        [HttpGet]
        public IHttpActionResult GetSignalPropertyhisAndLogs(string projId, string wireGroupIds)
        {
            try
            {
                var SignalTableName = ProjectSugar.TableName<ec_Wire_GroupEntity>(projId);
                var PropertyhisTableName = ProjectSugar.TableName<ec_wire_group_propertyhisEntity>(projId);
                var LogTableName = ProjectSugar.TableName<ec_wire_group_logEntity>(projId);
                var ids = wireGroupIds.Split(',');

                var signals = SqlSugarHelper.Db.Queryable<ec_Wire_GroupEntity>().AS(SignalTableName)
                    .Where(x => ids.Contains(x.Wire_Group_ID) && !x.DeleteFlg).ToList();

                var his = SqlSugarHelper.Db.Queryable<ec_wire_group_propertyhisEntity>().AS(PropertyhisTableName).Where(x => ids.Contains(x.WireGroupID)
                && !(string.IsNullOrEmpty(x.OldPropertyValue) && string.IsNullOrEmpty(x.NewPropertyValue))).ToList();
                var logs = SqlSugarHelper.Db.Queryable<ec_wire_group_logEntity>().AS(LogTableName).Where(x => ids.Contains(x.WireGroupID)).ToList();
                var users = SqlSugarHelper.Db.Queryable<UserEntity>().ToList();
                his.ForEach(x =>
                {
                    x.CreateUserName = users.FirstOrDefault(y => y.F_UserId == x.CreateUserID)?.F_RealName;
                });
                logs.ForEach(x =>
                {
                    x.CreateUserName = users.FirstOrDefault(y => y.F_UserId == x.CreateUserID)?.F_RealName;
                });

                signals.ForEach(x =>
                {
                    x.Propertyhis = his.Where(y => y.WireGroupID == x.Wire_Group_ID).OrderByDescending(y => y.CreateTime).ToList();
                    x.Logs = logs.Where(y => y.WireGroupID == x.Wire_Group_ID).OrderByDescending(y => y.CreateTime).ToList();
                });
                return Success(signals);

            }
            catch (System.Exception E)
            {
                return Fail(E.Message);
            }
        }
        /// <summary>
        /// 查询信号历史
        /// </summary>
        /// <param name="projId">项目ID</param>
        /// <param name="wireGroupIds">信号ID，多个用都逗号隔开</param>
        /// <returns></returns>
        [HttpGet]
        public IHttpActionResult GetSignalPropertyhis(string projId, string wireGroupIds)
        {
            try
            {
                var PropertyhisTableName = ProjectSugar.TableName<ec_wire_group_propertyhisEntity>(projId);
                var ids = wireGroupIds.Split(',');
                var his = SqlSugarHelper.Db.Queryable<ec_wire_group_propertyhisEntity>().AS(PropertyhisTableName)
                    .Where(x => ids.Contains(x.WireGroupID) 
                    && !(string.IsNullOrEmpty(x.OldPropertyValue) && string.IsNullOrEmpty(x.NewPropertyValue))).OrderByDescending(x => x.CreateTime).ToList();
                var pairs = new Dictionary<string, string>()
                {
                    {"Status", "状态" },
                    {"LinkedID", "关联ID" },
                    {"Group_Name", "信号名称" },
                    {"PanelID", "箱柜ID" },
                    {"StripID", "端子排ID" },
                    {"ChannelID", "通道ID" },
                    {"Group_Desc_EN", "英文描述" },
                    {"Group_Desc", "中文描述" },
                    {"IO_Type", "信号类型" },
                    {"Signal_Group", "信号的分组" },
                    {"Signal_SeqNo", "信号的序号" },
                    {"Code", "代码" },
                    {"Range_Min", "范围最小值" },
                    {"Range_Max", "范围最大值" },
                    {"Unit", "单位" },
                    {"Alarm_LL", "报警下限1" },
                    {"Alarm_L", "报警下限2" },
                    {"Alarm_H", "报警上限2" },
                    {"Alarm_HH", "报警上限1" },
                    {"AL_GRP", "延申报警组" },
                    {"BL_GRP", "抑制报警" },
                    {"Time_Delay", "延时" },
                    {"Supplier", "供应商" },
                    {"EquipName", "设备名" },
                    {"SENSOR_CODE", "传感器代码" },
                    {"VDR_Record", "VDR_Record" },
                    {"SLD", "slow down信号" },
                    {"SHD", "shut down信号" },
                    {"Remarks", "备注" },
                    {"ElecOnly", "信号归属" },
                    {"CommunicationPoint", "通讯点" },
                    {"ECC", "ECC" },
                    {"WCC", "WCC" },
                    {"BCC", "BCC" },
                    {"InOrOut", "IO类型" },
                    {"WHConsole", "驾驶室（控制台）" },
                    {"WHCPU", "驾驶室（计算机）" },
                    {"ECRConsole", "集控室（控制台）" },
                    {"ECRCPU", "集控室（计算机）" },
                    {"ShipOfficeConsole", "船舶办公室（控制台）" },
                    {"ShipOfficeCPU", "船舶办公室（计算机）" },
                    {"SafetyProt", "安全保护" },
                    {"ParentID", "父亲" },
                    {"DeleteFlg", "删除标记" },
                    {"CableName", "电缆位号" },
                    {"CableId", "母线ID" },
                    {"CreateUserID", "创建人" },
                    {"CreateTime", "创建时间" },
                    {"UpdateUserID", "更新人" },
                    {"UpdateTime", "更新时间" },
                    {"WireGroupTemplateID", "信号模板ID" },
                };
                var users = SqlSugarHelper.Db.Queryable<UserEntity>().ToList();
                his.ForEach(x =>
                {
                    if (x.PropertyName == "Status")
                    {
                        switch (x.OldPropertyValue)
                        {
                            case "1":
                                x.OldPropertyValue = "待删除";
                                break;
                            case "2":
                                x.OldPropertyValue = "新增的";
                                break;
                            case "3":
                                x.OldPropertyValue = "已关联";
                                break;
                            case "4":
                                x.OldPropertyValue = "已审核";
                                break;
                            case "5":
                                x.OldPropertyValue = "重新打开";
                                break;
                        }
                        switch (x.NewPropertyValue)
                        {
                            case "1":
                                x.NewPropertyValue = "待删除";
                                break;
                            case "2":
                                x.NewPropertyValue = "新增的";
                                break;
                            case "3":
                                x.NewPropertyValue = "已关联";
                                break;
                            case "4":
                                x.NewPropertyValue = "已审核";
                                break;
                            case "5":
                                x.NewPropertyValue = "重新打开";
                                break;
                        }
                    }
                    x.PropertyNameDec = pairs[x.PropertyName];
                    x.CreateUserName = users.FirstOrDefault(y => y.F_UserId == x.CreateUserID)?.F_RealName;
                });
                return Success(his);
            }
            catch (System.Exception E)
            {
                return Fail(E.Message);

            }
        }
        /// <summary>
        /// 新建信号名称时，从后台返回一个当前分组中可用的seqNo
        /// </summary>
        /// <param name="projId">项目编号</param>
        /// <param name="group">信号分组</param>
        /// <returns></returns>
        [HttpGet]
        public IHttpActionResult GetNextAvailableSeq(string projId, string group)
        {
            try
            {
                var tableName = ProjectSugar.TableName<ec_Wire_GroupEntity>(projId);
                var names = SqlSugarHelper.Db.Queryable<ec_Wire_GroupEntity>().AS(tableName)
                    .Where(x => x.Group_Name.StartsWith(group)).Select(x => x.Group_Name).ToList();
                List<int> seqNos = new List<int>();
                seqNos.Add(0);
                names.ForEach(x =>
                {
                    string seqNo;
                    if (group == "SLD" || group == "SHD")
                    {
                        seqNo = x.Substring(3);
                    }
                    else
                    {
                        seqNo = x.Substring(2);
                    }
                    var mac = new Regex("[0-9]+").Match(seqNo);
                    if (mac.Success)
                    {
                        seqNos.Add(int.Parse(mac.Value));
                    }
                });
                return Success($"{(seqNos.Max() + 1).ToString().PadLeft(3, '0')}");
            }
            catch (Exception ex)
            {
                return Fail(ex.Message);
            }
        }
        /// <summary>
        /// 查询信号日志
        /// </summary>
        /// <param name="projId">项目ID</param>
        /// <param name="wireGroupIds">信号ID，多个用都逗号隔开</param>
        /// <returns></returns>
        [HttpGet]
        public IHttpActionResult GetSignalLogs(string projId, string wireGroupIds)
        {
            try
            {
                var LogTableName = ProjectSugar.TableName<ec_wire_group_logEntity>(projId);
                var ids = wireGroupIds.Split(',');
                var logs = SqlSugarHelper.Db.Queryable<ec_wire_group_logEntity>().AS(LogTableName).Where(x => ids.Contains(x.WireGroupID)).OrderByDescending(x=> x.CreateTime).ToList();
                var users = SqlSugarHelper.Db.Queryable<UserEntity>().ToList();
                logs.ForEach(x =>
                {
                    x.CreateUserName = users.FirstOrDefault(y => y.F_UserId == x.CreateUserID)?.F_RealName;
                });
                return Success(logs);

            }
            catch (System.Exception E)
            {
                return Fail(E.Message);
            }
        }
        #region notice

        /// <summary>
        /// 查询信号的消息
        /// </summary>
        /// <param name="projId"></param>
        /// <param name="ID"></param>
        /// <returns></returns>
        [HttpGet]
        public IHttpActionResult GetNotification(string projId)
        {
            try
            {
                var NoticeTableName = ProjectSugar.TableName<ec_wire_group_noticeEntity>(projId);
                var SignalTableName = ProjectSugar.TableName<ec_Wire_GroupEntity>(projId);

                //SugarRedis 需要 NET Standard 2.1，不支持Framework
                var users = SqlSugarHelper.Db.Queryable<UserEntity>().ToList();
                #region 只需要对方的

                var _User = users.FirstOrDefault(x => x.F_UserId == LoginUserInfo.Get().userId);
                if (_User == null)
                {
                    throw new Exception("找不到UserEntity。");
                }
                var _Company = SqlSugarHelper.Db.Queryable<CompanyEntity>().First(x => x.F_CompanyId == _User.F_CompanyId);
                var DepartmentStr = "";
                Department _Department;
                if (_Company != null)
                {
                    DepartmentStr = _Company.F_FullName;
                    if (DepartmentStr.Contains("轮机"))
                    {
                        _Department = Department.轮机;
                    }
                    else
                    {
                        _Department = Department.电气;
                    }
                }
                else
                {
                    _Department = Department.电气;
                }
                var res = SqlSugarHelper.Db.Queryable<ec_wire_group_noticeEntity>().AS(NoticeTableName).
                    Where(x => !string.IsNullOrEmpty(x.WireGroupID)).
                    OrderByDescending(x => x.CreateTime).
                    Where(x => x.CompanyID == _Department).ToList();
                //Where(x => x.CompanyID == _Department).ToList();//收到本专业的通知即可
                #endregion
                var signals = SqlSugarHelper.Db.Queryable<ec_Wire_GroupEntity>().AS(SignalTableName).ToList();

                foreach (ec_wire_group_noticeEntity noticeEntity in res)
                {
                    var user_Send = users.FirstOrDefault(x => x.F_UserId == noticeEntity?.CreateUserID);
                    var user_Confrim = users.FirstOrDefault(x => x.F_UserId == noticeEntity?.UpdateUserID);
                    var signal = signals.FirstOrDefault(x => x.Wire_Group_ID == noticeEntity.WireGroupID);
                    if (signal != null)
                    {
                        noticeEntity.Group_Name = signal.Group_Name;
                        noticeEntity.Group_Desc = signal.Group_Desc;
                        noticeEntity.Group_Desc_EN = signal.Group_Desc_EN;
                        noticeEntity.IO_Type = signal.IO_Type;
                        noticeEntity.CreateUserName = user_Send?.F_RealName;
                        noticeEntity.UpdateUserName = user_Confrim?.F_RealName;
                        noticeEntity.Action = noticeEntity.ActionID.ToString();
                    }
                    else
                    {
                        //信号都没了
                        noticeEntity.WireGroupID = "-1";
                    }
                }
                return Success(res.Where(x => !string.IsNullOrEmpty(x.Group_Name) || x.WireGroupID != "-1").ToList());
            }
            catch (System.Exception E)
            {
                return Fail(E.Message);

            }
        }

        /// <summary>
        /// 读通知确认
        /// </summary>
        /// <param name="projId"></param>
        /// <param name="NoticeIds"></param>
        /// <returns></returns>
        [HttpPost]
        public IHttpActionResult ReadNotification(string projId, [FromBody] List<string> NoticeIds)
        {
            try
            {
                var bll = new ec_Wire_GroupBLL();
                var res = bll.ReadNotification(projId, NoticeIds);

                return Success(res);
            }
            catch (System.Exception E)
            {
                return Fail(E.Message);

            }
        }
        #endregion

    }
}